﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace SharpSoft.WPF.Controls
{
    /// <summary>
    /// 几何设计器基类
    /// </summary>
    public abstract class GeoDesignerBase : DependencyObject, IGeoDesigner
    {
        public GeoDesignerBase()
        {
            pathGeometry = new PathGeometry();

            handler_Original = new HandlerThumb() { Shape = HandlerThumbShape.Circle };
            handler_Direction = new HandlerThumb() { Shape = HandlerThumbShape.Triangles };

            this.Handlers = new ObservableCollection<HandlerThumb>() {
            handler_Original,handler_Direction
            };
            handler_Direction.DragDelta += Handler_Direction_DragDelta;
        }

        private void Handler_Direction_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            e.Handled = true;
            var v = new Vector(e.HorizontalChange, e.VerticalChange);
            this.Direction += v;
        }

        protected readonly PathGeometry pathGeometry;
        protected readonly HandlerThumb handler_Original, handler_Direction;
        #region IGeoDesigner
        /// <summary>
        /// 图形原点
        /// </summary>
        public Point OriginalPoint
        {
            get { return (Point)GetValue(OriginalPointProperty); }
            set { SetValue(OriginalPointProperty, value); }
        }

        public static readonly DependencyProperty OriginalPointProperty =
            DependencyProperty.Register("OriginalPoint", typeof(Point), typeof(GeoDesignerBase), new PropertyMetadata(default(Point)));
        /// <summary>
        /// 方向
        /// </summary>
        public Vector Direction
        {
            get { return (Vector)GetValue(DirectionProperty); }
            set { SetValue(DirectionProperty, value); }
        }

        public static readonly DependencyProperty DirectionProperty =
            DependencyProperty.Register("Direction", typeof(Vector), typeof(GeoDesignerBase), new PropertyMetadata(default(Vector)));

        /// <summary>
        /// 是否是设计模式
        /// </summary>
        public bool IsDesignMode
        {
            get { return (bool)GetValue(IsDesignModeProperty); }
            set { SetValue(IsDesignModeProperty, value); }
        }

        public static readonly DependencyProperty IsDesignModeProperty =
            DependencyProperty.Register("IsDesignMode", typeof(bool), typeof(GeoDesignerBase), new PropertyMetadata(default(bool)));
        /// <summary>
        /// 是否选中
        /// </summary>
        public bool IsActivated
        {
            get { return (bool)GetValue(IsActivatedProperty); }
            set { SetValue(IsActivatedProperty, value); }
        }

        public static readonly DependencyProperty IsActivatedProperty =
            DependencyProperty.Register("IsActivated", typeof(bool), typeof(GeoDesignerBase), new PropertyMetadata(default(bool)));



        /// <summary>
        /// 手柄集合
        /// </summary>
        public ObservableCollection<HandlerThumb> Handlers
        {
            get { return (ObservableCollection<HandlerThumb>)GetValue(HandlersProperty); }
            private set { SetValue(HandlersPropertyKey, value); }
        }
        private static DependencyPropertyKey HandlersPropertyKey = DependencyProperty.RegisterReadOnly("Handlers", typeof(ObservableCollection<HandlerThumb>), typeof(GeoDesignerBase), new PropertyMetadata(default(ObservableCollection<HandlerThumb>)));
        public static DependencyProperty HandlersProperty = HandlersPropertyKey.DependencyProperty;

        /// <summary>
        /// 渲染当前图形
        /// </summary>
        /// <param name="dc"></param>
        /// <param name="gc"></param>
        public virtual void Paint(DrawingContext dc, GeoControl gc)
        {
            var pen = new Pen(gc.BorderBrush, gc.BorderThickness.Left) { DashStyle = DashStyles.Solid, DashCap = PenLineCap.Flat, LineJoin = PenLineJoin.Round, };
            dc.DrawGeometry(gc.Background, pen, this.pathGeometry);

            if (this.IsActivated)
            {
                var pen1 = new Pen(gc.Foreground, 1) { DashStyle = new DashStyle(new double[] { 5, 5 }, 0), DashCap = PenLineCap.Flat, LineJoin = PenLineJoin.Round, };
                dc.DrawLine(pen1, this.OriginalPoint, this.OriginalPoint + this.Direction);
            }

        }

        /// <summary>
        /// 在图形需要重绘时触发
        /// </summary>
        public event EventHandler Updated;

        #endregion
        protected virtual void OnUpdated()
        {
            this.Updated?.Invoke(this, EventArgs.Empty);
        }

        /// <summary>
        /// 相关参数变化后重设手柄的位置
        /// </summary>
        protected virtual void rePositionHandlers()
        {
            handler_Original.Center = this.OriginalPoint;
            var op = this.OriginalPoint;
            var target = op + this.Direction;
            handler_Direction.Center = target;
            handler_Direction.Rotate.Angle = Vector.AngleBetween(new Vector(1, 0), this.Direction);

            handler_Direction.InvalidateVisual();

            this.Updated?.Invoke(this, EventArgs.Empty);

        }

        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            if (e.Property == OriginalPointProperty || e.Property == DirectionProperty)
            {
                this.rePositionHandlers();
            }
        }

    }
}
